`include "param_iopmp.v"
module  diopmp_check(
    input                          diopmpck_clk_i              ,
    input                          diopmpck_rst_n_i            ,
    
    // from diopmp_reg
    input [31:0]                  diopmpck_addrst_cnt_i        ,
    input [31:0]                  diopmpck_size_cnt_i          ,
    input [31:0]                  diopmpck_rule_i              ,
    input [`IOMODE-1:0]           diopmpck_mode_i              ,
    //to diopmp_reg        
    output                          diopmpck_error_o           ,
    output  [15:0]                  diopmpck_iohit_o           ,


    input   [31:0]               diopmpck_apb_paddr_i          ,
    input                        diopmpck_apb_penable_i        ,
    input   [2 :0]               diopmpck_apb_pprot_i          ,
    input                        diopmpck_apb_psel_i           ,
    input   [31:0]               diopmpck_apb_pwdata_i         ,
    input                        diopmpck_apb_pwrite_i         ,
    output  [31:0]               diopmpck_apb_check_prdata_o   ,

    input    [31:0]              diopmpck_apb_prdata_i         ,
    output   [31:0]              diopmpck_apb_check_paddr_o    ,
    output                       diopmpck_apb_check_penable_o  ,
    output   [2 :0]              diopmpck_apb_check_pprot_o    ,
    output                       diopmpck_apb_check_psel_o     ,
    output   [31:0]              diopmpck_apb_check_pwdata_o   ,
    output                       diopmpck_apb_check_pwrite_o   ,


    //to diopmp_control
    output                          diopmpck_penable_o,
    output                          diopmpck_pwrite_o ,
    output                          diopmpck_psel_o   ,
    //from diopmp_control
    input                           diopmpck_check_en_i,
    input                           diopmpck_rdck_i   ,
    input                           diopmpck_wrck_i
);




// reg [31:0]    check_rule; // 修改的check规则
reg [4:0]     state;
reg [4:0]     state_next;
wire          write_en;
wire          read_en;
wire [1:0]    pri_wr;
wire          bus_ieqo;
wire [15:0]   io_hit;
reg           bus_read_check_b;
wire          bus_read_access;

//old assign bus_ieqo  = ((~diopmpck_hwrite_i & pri_wr[0]) | (diopmpck_hwrite_i & pri_wr[1]) | (diopmpck_hprot_i[0]==1'b0)) & (diopmpck_check_en_i==1'b1);

//new
assign bus_ieqo  = ((diopmpck_rdck_i && pri_wr[0])   || 
                    (diopmpck_wrck_i && pri_wr[1])   || 
                    (diopmpck_apb_pprot_i[2]==1'b1)) && (diopmpck_check_en_i==1'b1);
                    


//更新检查规则
// always @(posedge diopmpck_clk_i or negedge diopmpck_rst_n_i) begin
//     if(!diopmpck_rst_n_i)
//         check_rule <= 32'hFFFF_FFFC;
//     else if(diopmpck_check_en_i == 1'b0)
//         check_rule <= diopmpck_rule_i;
//     else
//         check_rule <= check_rule;
// end

//limit read after read_en 
// always @(posedge diopmpck_clk_i or negedge diopmpck_rst_n_i) begin
//     if(!diopmpck_rst_n_i)
//         bus_read_check_b <= 1'h0;
//     else if(bus_ieqo == 1'b0 && read_en == 1'b1)
//         bus_read_check_b <= 1'h1;
//     else if(diopmpck_state_n_i[3] == 1'b1)
//         bus_read_check_b <= 1'h0;
//     else
//         bus_read_check_b <= bus_read_check_b;
// end



// assign bus_read_access = ~(bus_read_check_b & diopmpck_state_n_i[3]);



assign   diopmpck_apb_check_paddr_o  = diopmpck_apb_paddr_i  ;
assign   diopmpck_apb_check_pwrite_o = diopmpck_apb_pwrite_i ;
assign   diopmpck_apb_check_pprot_o  = diopmpck_apb_pprot_i  ;
assign   diopmpck_apb_check_pwdata_o = diopmpck_apb_pwdata_i ;
assign   diopmpck_apb_check_psel_o   = (bus_ieqo == 1'b1) ? diopmpck_apb_psel_i : 1'b0;
assign   diopmpck_apb_check_penable_o= (bus_ieqo == 1'b1) ? diopmpck_apb_penable_i : 1'b0;
assign   diopmpck_apb_check_prdata_o = (bus_ieqo == 1'b1) ? diopmpck_apb_prdata_i : 32'd0;


assign   diopmpck_error_o  = (bus_ieqo == 1'b1) ? 1'b0 : 1'b1;
assign   diopmpck_iohit_o  = (bus_ieqo == 1'b1) ? 16'd0 : io_hit;
assign   diopmpck_penable_o  = diopmpck_apb_penable_i;
assign   diopmpck_pwrite_o  = diopmpck_apb_pwrite_i; 
assign   diopmpck_psel_o    = diopmpck_apb_psel_i; 


diopmp_addr_match u_diopmp_addr_match 
(
    .daddrmt_haddr_i       (diopmpck_apb_paddr_i     ),
    .daddrmt_hprot_i       (diopmpck_apb_pprot_i     ),
    .daddrmt_addrst_cnt_i  (diopmpck_addrst_cnt_i),
    .daddrmt_size_cnt_i    (diopmpck_size_cnt_i  ),
    .daddrmt_rule_i        (diopmpck_rule_i      ),
    .daddrmt_mode_i        (diopmpck_mode_i      ),
    .daddrmt_pri_o         (pri_wr               ),     
    .daddrmt_hit_o         (io_hit               )
);

endmodule
